#include "Camera.h"

#define SCREEN_WIDTH 800.0f
#define SCREEN_HEIGHT 600.0f

CCamera::CCamera(void)
{
	Init(NULL);
}

void CCamera::Init(IDirect3DDevice9* dev)
{
	m_pDevice = dev;
	m_fAlpha = m_fBeta = 0.5f;
	m_fRadius = 200.0f;
	m_fFov = D3DX_PI / 4.0f;

	m_Eye = D3DXVECTOR3(50.0f, 50.0f, 50.0f);
	m_Focus = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
}

void CCamera::Scroll(D3DXVECTOR3 vec)
{
	D3DXVECTOR3 newFocus = m_Focus + vec;

	if(newFocus.x > -50.0f && newFocus.x < 50.0f &&
	   newFocus.z > -50.0f && newFocus.z < 50.0f)
	   m_Focus = newFocus;
}
void CCamera::Pitch(float f)
{
	m_fBeta += f;
	
	if(m_fBeta > D3DX_PI / 2.0f) m_fBeta = D3DX_PI / 2.0f - 0.01f;
	if(m_fBeta < 0.3f) m_fBeta = 0.3f;
}

void CCamera::Yaw(float f)
{
	m_fAlpha += f;
	if(m_fAlpha > D3DX_PI * 2.0f) m_fAlpha -= D3DX_PI * 2.0f;
	if(m_fAlpha < -D3DX_PI * 2.0f) m_fAlpha += D3DX_PI * 2.0f;
}

void CCamera::Zoom(float f)
{
	m_fFov += f;
	if(m_fFov < 0.1f) m_fFov = 0.1f;
	if(m_fFov > D3DX_PI / 2.0f) m_fFov = D3DX_PI / 2.0f;
}

void CCamera::ChangeRadius(float f)
{
	m_fRadius += f;
	if(m_fRadius < 5.0f) m_fRadius = 5.0f;
	if(m_fRadius > 400.0f) m_fRadius = 400.0f;

}

void CCamera::Update(float fTDelta)
{
	//	Restrict movement to the xz-plane
	m_Right.y = m_Look.y = 0.0f;
	D3DXVec3Normalize(&m_Look, &m_Look);
	D3DXVec3Normalize(&m_Right, &m_Right);

	//	Scroll
	if(KEYDOWN(VK_LEFT)) Scroll(-m_Right * fTDelta * 20.0f);
	if(KEYDOWN(VK_RIGHT)) Scroll(m_Right * fTDelta * 20.0f);
	if(KEYDOWN(VK_UP)) Scroll(m_Look * fTDelta * 20.0f);
	if(KEYDOWN(VK_DOWN)) Scroll(-m_Look * fTDelta * 20.0f);

	//	Change Camera Angle
	if(KEYDOWN('A'))Yaw(-fTDelta);
	if(KEYDOWN('D'))Yaw(fTDelta);
	if(KEYDOWN('W'))Pitch(fTDelta);
	if(KEYDOWN('S'))Pitch(-fTDelta);

	if(KEYDOWN(VK_SHIFT))
	{
		//	Zoom
		if(KEYDOWN(VK_ADD))Zoom(-fTDelta);
		if(KEYDOWN(VK_SUBTRACT))Zoom(fTDelta);
	}
	else
	{
		if(KEYDOWN(VK_ADD)) ChangeRadius(-fTDelta * 100.0f);
		if(KEYDOWN(VK_SUBTRACT)) ChangeRadius(fTDelta * 100.0f);
	}

	//	Calculate eye position
	float fSideRadius = m_fRadius * cos(m_fBeta);
	float fHeight = m_fRadius * sin(m_fBeta);

	m_Eye = D3DXVECTOR3(m_Focus.x + fSideRadius * cos(m_fAlpha),
						m_Focus.y + fHeight,
						m_Focus.z + fSideRadius * sin(m_fAlpha));

	if(m_pDevice != NULL)
	{
		m_pDevice->SetTransform(D3DTS_VIEW, &GetViewMatrix());
		m_pDevice->SetTransform(D3DTS_PROJECTION, &GetProjectionMatrix());
	}

}

D3DXMATRIX CCamera::GetViewMatrix()
{
	D3DXMATRIX matView;
	D3DXMatrixLookAtLH(&matView, &m_Eye, &m_Focus, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));

	m_Right.x = matView(0,0);
	m_Right.y = matView(1,0);
	m_Right.z = matView(2,0);
	D3DXVec3Normalize(&m_Right, &m_Right);

	m_Look.x = matView(0,2);
	m_Look.y = matView(1,2);
	m_Look.z = matView(2,2);
	D3DXVec3Normalize(&m_Look, &m_Look);

	return matView;
}

D3DXMATRIX CCamera::GetProjectionMatrix()
{
	D3DXMATRIX matProj;
	float fAspect = SCREEN_WIDTH / SCREEN_HEIGHT;
	D3DXMatrixPerspectiveFovLH(&matProj, m_fFov, fAspect, 1.0f, 1000.0f);
	return matProj;
}

